package com.cb.web.wasf.sample.web.validation;

import com.cb.web.wasf.Message.FreeMessage;
import com.cb.web.wasf.State;
import com.cb.web.wasf.StringUtils;
import org.hibernate.validator.constraints.impl.EmailValidator;

/**
 * @author CBO
 */
public abstract class Check {

    public abstract boolean check();

    public abstract String getFailMessage();

    public static Check notEmpty(final String value, final String fieldName) {
        return new Check() {

            @Override
            public boolean check() {
                return !StringUtils.isBlank(value);
            }

            @Override
            public String getFailMessage() {
                return "Le champ " + fieldName + " est obligatoire";
            }
        };
    }

    public static Check minLength(final String value, final int minLength, final String fieldName) {
        return new Check() {

            @Override
            public boolean check() {
                if (value == null) {
                    return false;
                } else {
                    return value.length() >= minLength;
                }
            }

            @Override
            public String getFailMessage() {
                return "Le champ " + fieldName + " doit comporter au minimum " + minLength + " caractères";
            }
        };
    }

    public static Check sameValue(final String firstValue, final String secondValue, final String firstFieldName, final String secondFieldName) {
        return new Check() {

            @Override
            public boolean check() {
                if (firstValue == null && secondValue == null) {
                    return true;
                } else if (secondValue == null) {
                    return firstValue.equals(secondValue); 
                } else {
                    return secondValue.equals(firstValue); 
                }
            }

            @Override
            public String getFailMessage() {
                return "Le champ " + firstFieldName + " doit être égal au champ " + secondFieldName;
            }
        };
    }
    
    public static Check mail(final String value, final String fieldName) {
        return new Check() {

            @Override
            public boolean check() {
                EmailValidator emailValidator = new EmailValidator();
                return emailValidator.isValid(value, null);
            }

            @Override
            public String getFailMessage() {
                return "Le champ " + fieldName + " n'est pas une adresse électronique valide";
            }
        };
    }

    public static Check conditional(final Check conditionned, final boolean condition) {
        return new Check() {

            @Override
            public boolean check() {
                if (condition) {
                    return conditionned.check();
                } else {
                    return true;
                }
            }

            @Override
            public String getFailMessage() {
                return conditionned.getFailMessage();
            }
        };
    }

    public static Check conditional(final Check conditionned, final Check condition) {
        return new Check() {

            @Override
            public boolean check() {
                if (condition.check()) {
                    return conditionned.check();
                } else {
                    return true;
                }
            }

            @Override
            public String getFailMessage() {
                return conditionned.getFailMessage();
            }
        };
    }

    public static boolean check(State state, Check... checks) {
        boolean toReturn = true;
        for (Check check : checks) {
            if (!check.check()) {
                toReturn = false;
                state.addMessage(new FreeMessage(check.getFailMessage()));
            }
        }
        return toReturn;
    }
}
